package com.ticket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ticket.entity.Match;
import com.ticket.entity.TicketOrder;
import com.ticket.entity.TicketPrice;
import com.ticket.entity.VenueSection;
import com.ticket.mapper.TicketOrderMapper;
import com.ticket.service.IMatchService;
import com.ticket.service.ISeatAllocationService;
import com.ticket.service.ITicketOrderService;
import com.ticket.service.ITicketPriceService;
import com.ticket.service.IVenueSectionService;
import com.ticket.vo.CreateOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class TicketOrderServiceImpl extends ServiceImpl<TicketOrderMapper, TicketOrder> implements ITicketOrderService {

    @Autowired
    private ITicketPriceService ticketPriceService;

    @Autowired
    private IMatchService matchService;

    @Autowired
    private IVenueSectionService venueSectionService;

    @Autowired
    private ISeatAllocationService seatAllocationService;

    @Override
    @Transactional
    public Long createOrder(Long userId, CreateOrderVO orderVO) {
        // 检查门票是否可用
        TicketPrice ticketPrice = ticketPriceService.getById(orderVO.getPriceId());
        if (ticketPrice == null) {
            throw new RuntimeException("票价信息不存在");
        }

        // 获取可用座位
        Integer seatNumber = seatAllocationService.getNextAvailableSeat(orderVO.getMatchId(), orderVO.getSectionId());
        if (seatNumber == null) {
            throw new RuntimeException("该区域已售罄");
        }

        // 创建订单
        TicketOrder order = new TicketOrder();
        order.setUserId(userId);
        order.setMatchId(orderVO.getMatchId());
        order.setSectionId(orderVO.getSectionId());
        order.setTicketNumber(seatNumber);
        order.setTotalAmount(ticketPrice.getPrice());
        order.setName(orderVO.getName());
        order.setPhone(orderVO.getPhone());
        order.setEmail(orderVO.getEmail());
        order.setStatus("PENDING");
        order.setCreatedAt(LocalDateTime.now());

        // 保存订单
        save(order);

        // 锁定座位
        seatAllocationService.allocateSeat(orderVO.getMatchId(), orderVO.getSectionId(), seatNumber, "RESERVED");

        return order.getId();
    }

    @Override
    @Transactional
    public boolean payOrder(Long userId, Long orderId) {
        TicketOrder order = this.getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new RuntimeException("订单不存在或不属于当前用户");
        }

        if (!"PENDING".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不正确，无法支付");
        }

        order.setStatus("PAID");
        order.setPaidAt(LocalDateTime.now());

        return this.updateById(order);
    }

    @Override
    @Transactional
    public boolean cancelOrder(Long userId, Long orderId) {
        TicketOrder order = this.getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new RuntimeException("订单不存在或不属于当前用户");
        }

        if (!"PENDING".equals(order.getStatus()) && !"PAID".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不正确，无法取消");
        }

        // 更新座位状态为可用
        seatAllocationService.updateSeatStatus(order.getMatchId(), order.getSectionId(), order.getTicketNumber(), "AVAILABLE");

        order.setStatus("CANCELLED");

        return this.updateById(order);
    }

    @Override
    public Page<TicketOrder> getUserOrders(Long userId, int page, int size, String status) {
        Page<TicketOrder> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<TicketOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TicketOrder::getUserId, userId);

        // 如果指定了状态，则按状态筛选
        if (status != null && !status.equals("ALL")) {
            queryWrapper.eq(TicketOrder::getStatus, status);
        }

        queryWrapper.orderByDesc(TicketOrder::getCreatedAt);

        return this.page(pageParam, queryWrapper);
    }

    @Override
    public Integer allocateSeatNumber(Long matchId, Long sectionId) {
        // 获取已分配的座位号
        List<Integer> occupiedSeats = baseMapper.getOccupiedSeatNumbers(matchId, sectionId);

        // 获取区域容量
        VenueSection section = venueSectionService.getById(sectionId);
        if (section == null) {
            return null;
        }

        // 如果所有座位都已分配，返回null
        if (occupiedSeats.size() >= section.getCapacity()) {
            return null;
        }

        // 找到最小的未分配座位号
        Set<Integer> occupiedSet = new HashSet<>(occupiedSeats);
        for (int i = 1; i <= section.getCapacity(); i++) {
            if (!occupiedSet.contains(i)) {
                return i;
            }
        }

        return null;
    }

    @Override
    @Transactional
    public boolean refundOrder(Long userId, Long orderId) {
        TicketOrder order = this.getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new RuntimeException("订单不存在或不属于当前用户");
        }

        if (!"PAID".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不正确，无法退款");
        }

        // 检查比赛是否已开始
        Match match = matchService.getById(order.getMatchId());
        if (match == null) {
            throw new RuntimeException("比赛信息不存在");
        }

        if (match.getMatchTime().isBefore(LocalDateTime.now())) {
            throw new RuntimeException("比赛已开始，无法退票");
        }

        // 更新座位状态为可用
        seatAllocationService.updateSeatStatus(order.getMatchId(), order.getSectionId(), order.getTicketNumber(), "AVAILABLE");

        // 更新订单状态
        order.setStatus("REFUNDED");

        return this.updateById(order);
    }
}
